using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


using System.Xml;
using Microsoft.Xna.Framework.Content;
using System.IO;

namespace D2DEngine.Tile
{

    public class TileMapProcessor
    {
        public TileMapProcessor()
        {

        }


        public static D2DTileMap Load(string fileName, ContentManager content)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(fileName);

            D2DTileMap map = new D2DTileMap();

            XmlNode textureNode = xml.GetElementsByTagName("FileName")[0];

            string textureFileName = Path.GetFileNameWithoutExtension((textureNode.InnerText));
            D2DTileSet tileSet = new D2DTileSet(content.Load<Texture2D>(textureFileName));
            map.TileSet = tileSet; 

            XmlNode dimensionsNode = xml.GetElementsByTagName("MAP_DIMENSIONS")[0];

            foreach (XmlNode node in dimensionsNode.ChildNodes)
            {
                if (node.Name == "Tile_Size")
                    map.TileSet.TileSize = int.Parse(node.InnerText);

                if (node.Name == "Width")
                    map.Width = int.Parse(node.InnerText);

                if (node.Name == "Height")
                    map.Height = int.Parse(node.InnerText);
            }

            // Collision layer
            XmlNode collisionNode = xml.GetElementsByTagName("CollisionLayer")[0];
            map.CollisionLayer = ParseCollisionLayer(collisionNode, map.Width, map.Height);

            // Monster layer
            XmlNode monsterNode = xml.GetElementsByTagName("MonsterLayer")[0];
            map.MonsterLayer = ParseMonsterLayer(monsterNode, map.Width, map.Height);

            if(monsterNode != null)
                map.MonsterLayer = ParseMonsterLayer(monsterNode, map.Width, map.Height);

            XmlNodeList layerNodeList = xml.GetElementsByTagName("Layer");

            foreach (XmlNode layerNode in layerNodeList)
            {
                map.Layers.Add(ParseTileLayer(layerNode, map.Width, map.Height));
            }

            return map;
        }

        private static D2DTileLayer ParseTileLayer(XmlNode node, int mapWidth, int mapHeight)
        {
            D2DTileLayer layer = new D2DTileLayer(mapWidth, mapHeight);
            //layer.Depth = XmlConvert.ToSingle(node.Attributes["depth"].Value);

            string rowInfo;
            string[] rowCells;
            int rowID = 0;

            foreach (XmlNode rowNode in node.ChildNodes)
            {
                rowInfo = rowNode.InnerText;
                rowCells = rowInfo.Split(',');

                for (int i = 0; i < rowCells.Length; i++)
                {
                    layer.Layout[rowID, i] = int.Parse(rowCells[i]);
                }

                rowID++;
            }

            return layer;
        }

        private static D2DCollisionLayer ParseCollisionLayer(XmlNode node, int mapWidth, int mapHeight)
        {
            D2DCollisionLayer layer = new D2DCollisionLayer(mapWidth, mapHeight);

            string rowInfo;
            string[] rowCells;
            int rowID = 0;

            foreach (XmlNode rowNode in node.ChildNodes)
            {
                rowInfo = rowNode.InnerText;
                rowCells = rowInfo.Split(',');

                for (int i = 0; i < rowCells.Length; i++)
                {
                    layer.Layout[rowID, i] = int.Parse(rowCells[i]);
                }

                rowID++;
            }

            return layer;
        }

        private static D2DMonsterLayer ParseMonsterLayer(XmlNode node, int mapWidth, int mapHeight)
        {
            D2DMonsterLayer layer = new D2DMonsterLayer(mapWidth, mapHeight);

            string rowInfo;
            string[] rowCells;
            int rowID = 0;

            foreach (XmlNode rowNode in node.ChildNodes)
            {
                rowInfo = rowNode.InnerText;
                rowCells = rowInfo.Split(',');

                for (int i = 0; i < rowCells.Length; i++)
                {
                    layer.Layout[rowID, i] = int.Parse(rowCells[i]);
                }

                rowID++;
            }

            return layer;
        }
    }
}